﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GeneralTheGame
{
    public class GameTests
    {

        static void PrintCurrentScoreTable(List<int> table, Player currentPlayer)
        {
            var playerCombinations = currentPlayer.PlayerCombinations;
            Console.WriteLine("Ones: {0}; Used: {1}; Player score: {2}", table[0], playerCombinations[0] ? "yes" : "no", currentPlayer.PlayerScore[0]);
            Console.WriteLine("Twos: {0}; Used: {1}; Player score: {2}", table[1], playerCombinations[1] ? "yes" : "no", currentPlayer.PlayerScore[1]);
            Console.WriteLine("Threes: {0}; Used: {1}; Player score: {2}", table[2], playerCombinations[2] ? "yes" : "no", currentPlayer.PlayerScore[2]);
            Console.WriteLine("Fours: {0}; Used: {1}; Player score: {2}", table[3], playerCombinations[3] ? "yes" : "no", currentPlayer.PlayerScore[3]);
            Console.WriteLine("Fives: {0}; Used: {1}; Player score: {2}", table[4], playerCombinations[4] ? "yes" : "no", currentPlayer.PlayerScore[4]);
            Console.WriteLine("Sixes: {0}; Used: {1}; Player score: {2}", table[5], playerCombinations[5] ? "yes" : "no", currentPlayer.PlayerScore[5]);
            Console.WriteLine("One pair: {0}; Used: {1}; Player score: {2}", table[6], playerCombinations[7] ? "yes" : "no", currentPlayer.PlayerScore[7]);
            Console.WriteLine("Two pairs: {0}; Used: {1}; Player score: {2}", table[7], playerCombinations[8] ? "yes" : "no", currentPlayer.PlayerScore[8]);
            Console.WriteLine("Three of a kind: {0}; Used: {1}; Player score: {2}", table[8], playerCombinations[9] ? "yes" : "no", currentPlayer.PlayerScore[9]);
            Console.WriteLine("Four of a kind: {0}; Used: {1}; Player score: {2}", table[9], playerCombinations[10] ? "yes" : "no", currentPlayer.PlayerScore[10]);
            Console.WriteLine("Full House: {0}; Used: {1}; Player score: {2}", table[10], playerCombinations[11] ? "yes" : "no", currentPlayer.PlayerScore[11]);
            Console.WriteLine("Small straight: {0}; Used: {1}; Player score: {2}", table[11], playerCombinations[12] ? "yes" : "no", currentPlayer.PlayerScore[12]);
            Console.WriteLine("Large straight: {0}; Used: {1}; Player score: {2}", table[12], playerCombinations[13] ? "yes" : "no", currentPlayer.PlayerScore[13]);
            Console.WriteLine("Chance: {0}; Used: {1}; Player score: {2}", table[13], playerCombinations[14] ? "yes" : "no", currentPlayer.PlayerScore[14]);
            Console.WriteLine("Generale: {0}; Used: {1}; Player score: {2}", table[14], playerCombinations[15] ? "yes" : "no", currentPlayer.PlayerScore[15]);
            Console.WriteLine();
        }

        static string[] commands = 
        {
            "one",
            "two",
            "three",
            "four",
            "five",
            "six",
            "one-pair",
            "two-pairs",
            "three-of-a-kind",
            "four-of-a-kind",
            "full-house",
            "small-straight",
            "large-straight",
            "chance",
            "generale"
        };

        static bool ParseCommand(string command, Player player, List<int> score = null)
        {
            string[] split = command.Split(' ');
            switch (split[0])
            {
                case "roll":
                    if (split.Length == 1)
                    {
                        player.RollAllDice();
                        return false;
                    }
                    else
                    {
                        var diceToRoll = new List<int>();
                        for (int i = 1; i < split.Length; i++)
                        {
                            diceToRoll.Add(int.Parse(split[i]));
                        }
                        player.ThrowDice(diceToRoll);
                        return false;
                    }
                case "end":
                    return true;
                default:
                    if (!commands.Contains(command))
                    {
                        throw new ArgumentException("Unrecognized command!");
                    }
                    else
                    {
                        switch (command)
                        {
                            case "one":
                                player.SetPlayerCombination(0, score[0]);
                                return true;
                            case "two":
                                player.SetPlayerCombination(1, score[1]);
                                return true;
                            case "three":
                                player.SetPlayerCombination(2, score[2]);
                                return true;
                            case "four":
                                player.SetPlayerCombination(3, score[3]);
                                return true;
                            case "five":
                                player.SetPlayerCombination(4, score[4]);
                                return true;
                            case "six":
                                player.SetPlayerCombination(5, score[5]);
                                return true;
                            case "one-pair":
                                player.SetPlayerCombination(6, score[6]);
                                return true;
                            case "two-pairs":
                                player.SetPlayerCombination(7, score[7]);
                                return true;
                            case "three-of-a-kind":
                                player.SetPlayerCombination(8, score[8]);
                                return true;
                            case "four-of-a-kind":
                                player.SetPlayerCombination(9, score[9]);
                                return true;
                            case "full-house":
                                player.SetPlayerCombination(10, score[10]);
                                return true;
                            case "small-straight":
                                player.SetPlayerCombination(11, score[11]);
                                return true;
                            case "large-straight":
                                player.SetPlayerCombination(12, score[12]);
                                return true;
                            case "chance":
                                player.SetPlayerCombination(13, score[13]);
                                return true;
                            case "generale":
                                player.SetPlayerCombination(14, score[14]);
                                return true;
                            default:
                                break;
                        }
                    }
                return false;
            }

        }


        static Random randomGenerator = new Random();

        static ConsoleColor RandomColor()
        {
            List<ConsoleColor> colors = new List<ConsoleColor>()
            {
                ConsoleColor.Black,
                ConsoleColor.Blue,
                ConsoleColor.Cyan,
                ConsoleColor.DarkBlue,
                ConsoleColor.DarkCyan,
                ConsoleColor.DarkGray,
                ConsoleColor.DarkGreen,
                ConsoleColor.DarkMagenta,
                ConsoleColor.DarkRed,
                ConsoleColor.DarkYellow,
                ConsoleColor.Gray,
                ConsoleColor.Green,
                ConsoleColor.Magenta,
                ConsoleColor.Red,
                ConsoleColor.White,
                ConsoleColor.Yellow,
            };

            return colors[randomGenerator.Next(0, colors.Count)];
        }

        static void Main()
        {
            int playersNumber;
            Console.Write("Enter the number of players: ");
            int.TryParse(Console.ReadLine(), out playersNumber);

            Player[] players = new Player[playersNumber];

            for (int i = 0; i < playersNumber; i++)
            {
                Console.Write("Enter {0} player name: ", i + 1);
                string currentName = Console.ReadLine();
                players[i] = new Player(currentName, RandomColor());
            }

            int loops = 15;
            while (loops >= 0)
            {
                loops--;
                for (int i = 0; i < players.Length; i++)
                {
                    Console.Write("It's ");
                    Console.ForegroundColor = players[i].PlayerColor;
                    Console.Write("{0}", players[i].PlayerName);
                    Console.ResetColor();
                    Console.WriteLine("'s turn!");
                    Console.WriteLine("Type \"roll\" to roll the dice");

                    for (int j = 0; j < 4; j++)
                    {
                        string command = Console.ReadLine();
                        Console.Clear();

                        List<int> score = null;
                        if (j != 0)
                        {
                            score = CombinationDetection.DetectCombinations(players[i].PlayerDice);
                        }
                        bool end = false;
                        try
                        {
                            end = ParseCommand(command, players[i], score);
                        }
                        catch (ArgumentException)
                        {
                            Console.WriteLine("Unrecognised command, please try again");
                            command = Console.ReadLine();
                            end = ParseCommand(command, players[i], score);
                        }


                        score = CombinationDetection.DetectCombinations(players[i].PlayerDice);

                        if (end)
                        {
                            break;
                        }

                        StringBuilder sb = new StringBuilder();

                        for (int k = 0; k < players[i].PlayerDice.Count; k++)
                        {
                            sb.AppendFormat("{0} ", players[i].GetLastDieThrow(k + 1));
                        }

                        Console.WriteLine(sb.ToString());

                        PrintCurrentScoreTable(score, players[i]);

                    }
                }

                if (loops == 0)
                {
                    for (int i = 0; i < players.Length; i++)
                    {
                        Console.WriteLine("{0}'s score is: {1}", players[i].PlayerName, players[i].TotalPlayerScore);
                    }
                }
            }


            //Player player = new Player("NasC0", RandomColor());

            //for (int i = 0; i < 3; i++)
            //{
            //    string command = Console.ReadLine();

            //    Console.Clear();

            //    ParseCommand(command, player);

            //    StringBuilder sb = new StringBuilder();
            //    for (int j = 0; j < player.PlayerDice.Count; j++)
            //    {
            //        sb.AppendFormat("{0} ", player.GetLastDieThrow(j + 1));
            //    }
            //    Console.WriteLine(sb.ToString());

            //    var score = CombinationDetection.DetectCombinations(player.PlayerDice);

            //    PrintCurrentScoreTable(score);

            //    Console.WriteLine(score.Count);
            //}

        }
    }
}
